package ru.niir.goodfil.ui.tasks;

import org.apache.log4j.Logger;
import ru.niir.goodfil.audit.client.AuditService;
import ru.niir.goodfil.audit.domain.enums.EnviromentSubsystem;
import ru.niir.goodfil.audit.service.AuditServiceImpl;
import ru.niir.goodfil.audit.service.DefaultConfiguration;
import ru.niir.goodfil.audit.util.Assert;
import ru.niir.goodfil.audit.util.BooleanReference;
import ru.niir.goodfil.db.GoodfilFactory;
import ru.niir.goodfil.db.handlers.Goodfil;

import java.util.TimerTask;

public class EnviromentValidationTask extends TimerTask {
    private static final Logger logger = Logger.getLogger(EnviromentValidationTask.class);

    public static final String ENV_NAMES_MAILER_KEY = ".env.names.mailer";

    public static final String ENV_NAMES_MAILER_DEFAULT = "/bin/sh ./GoodwillMailer.sh";

    public static final String ENV_NAMES_BACKUPS_KEY = ".env.names.backups";

    public static final String ENV_NAMES_BACKUPS_DEFAULT = "backup_goodwill_store_forever";

    public static final String ENV_NAMES_1C_KEY = ".env.names.1c";

    public static final String ENV_NAMES_1C_DEFAULT = "Goodwill1C.jar";

    public static final String START_MAILER_CMD_KEY = ".cmd.mailer.start";

    public static final String STOP_MAILER_CMD_KEY = ".cmd.mailer.stop";

    public static final String START_MAILER_CMD_DEFAULT = "/home/sazonov/scripts/mailer_start.sh";

    public static final String STOP_MAILER_CMD_DEFAULT = "/home/sazonov/scripts/mailer_stop.sh";

    public static final String START_BACKUPS_CMD_KEY = ".cmd.backups.start";

    public static final String STOP_BACKUPS_CMD_KEY = ".cmd.backups.stop";

    public static final String START_BACKUPS_CMD_DEFAULT = "/home/sazonov/scripts/backups_start.sh";

    public static final String STOP_BACKUPS_CMD_DEFAULT = "/home/sazonov/scripts/backups_stop.sh";

    public static final String START_1C_CMD_KEY = ".cmd.1c.start";

    public static final String STOP_1C_CMD_KEY = ".cmd.1c.stop";

    public static final String START_1C_CMD_DEFAULT = "/home/sazonov/scripts/c1_start.sh";

    public static final String STOP_1C_CMD_DEFAULT = "/home/sazonov/scripts/c1_stop.sh";

    private final BooleanReference lastMailerValidationResult;

    private final BooleanReference lastBackuperValidationResult;

    private final BooleanReference lastC1IntegrationValidationResult;

    public EnviromentValidationTask(BooleanReference lastMailerValidationResult, BooleanReference lastBackuperValidationResult, BooleanReference lastC1IntegrationValidationResult) {
        this.lastMailerValidationResult = lastMailerValidationResult;
        this.lastBackuperValidationResult = lastBackuperValidationResult;
        this.lastC1IntegrationValidationResult = lastC1IntegrationValidationResult;
    }

    @Override
    public void run() {
        logger.debug("EnviromentValidationTask call");

        AuditService auditService = new AuditServiceImpl(new DefaultConfiguration());

        Goodfil gf = GoodfilFactory.getInstance();

        gf.createIfNotExists(ENV_NAMES_MAILER_KEY, ENV_NAMES_MAILER_DEFAULT);
        gf.createIfNotExists(ENV_NAMES_BACKUPS_KEY, ENV_NAMES_BACKUPS_DEFAULT);
        gf.createIfNotExists(ENV_NAMES_1C_KEY, ENV_NAMES_1C_DEFAULT);

        String mailerName = gf.get(ENV_NAMES_MAILER_KEY);
        String backupsName = gf.get(ENV_NAMES_BACKUPS_KEY);
        String c1Name = gf.get(ENV_NAMES_1C_KEY);

        Assert.notBlank(mailerName);
        Assert.notBlank(backupsName);
        Assert.notBlank(c1Name);

        try {
            boolean result = ru.niir.goodfil.ui.utils.Process.exists(mailerName);

            if (result != lastMailerValidationResult.getValue()) {
                if (result) {
                    auditService.logEnviromentSubsystemFound(EnviromentSubsystem.MAILER);
                } else {
                    auditService.logEnviromentSubsystemLost(EnviromentSubsystem.MAILER);
                }
                lastMailerValidationResult.setValue(result);
            }

            if (!result) {
                logger.error("ENVIROMENT ERROR: Mailer [" + mailerName + "]");

                try {
                    logger.debug("Trying to restart mailer...");
                    gf.createIfNotExists(START_MAILER_CMD_KEY, START_MAILER_CMD_DEFAULT);
                    Runtime.getRuntime().exec(gf.get(START_MAILER_CMD_KEY));
                } catch (Exception e) {
                    logger.error("Failed to restart mailer: " + e);
                }
            }
        } catch (Exception e) {
            logger.error("Cannot validate enviroment: Mailer: " + e.getMessage());
        }

        try {
            boolean result = ru.niir.goodfil.ui.utils.Process.exists(backupsName);

            if (result != lastBackuperValidationResult.getValue()) {
                if (result) {
                    auditService.logEnviromentSubsystemFound(EnviromentSubsystem.ARCHIVER);
                } else {
                    auditService.logEnviromentSubsystemLost(EnviromentSubsystem.ARCHIVER);
                }
                lastBackuperValidationResult.setValue(result);
            }

            if (!result) {
                logger.error("ENVIROMENT ERROR: Backups [" + backupsName + "]");

                try {
                    logger.debug("Trying to restart backups...");
                    gf.createIfNotExists(START_BACKUPS_CMD_KEY, START_BACKUPS_CMD_DEFAULT);
                    Runtime.getRuntime().exec(gf.get(START_BACKUPS_CMD_KEY));
                } catch (Exception e) {
                    logger.error("Failed to restart backups: " + e);
                }
            }
        } catch (Exception e) {
            logger.error("Cannot validate enviroment: Backups: " + e.getMessage());
        }

        try {
            boolean result = ru.niir.goodfil.ui.utils.Process.exists(c1Name);

            if (result != lastC1IntegrationValidationResult.getValue()) {
                if (result) {
                    auditService.logEnviromentSubsystemFound(EnviromentSubsystem.C1_INTEGRATION);
                } else {
                    auditService.logEnviromentSubsystemLost(EnviromentSubsystem.C1_INTEGRATION);
                }
                lastC1IntegrationValidationResult.setValue(result);
            }

            if (!result) {
                logger.error("ENVIROMENT ERROR: 1C [" + c1Name + "]");
            }
        } catch (Exception e) {
            logger.error("Cannot validate enviroment: 1C: " + e.getMessage());
        }
    }
}
